import { ref } from 'vue';

import DialogVue from './Dialog.vue';

import { useCreateApp } from '@/hooks';

const dialogMap = new Map();

type DialogConfig =
  | {
      cid: string; // 建议 组件名 + 特殊字符（id）
      content: object; // 组件
      draggable?: boolean; // 是否可拖拽
      data?: object; // props data
      offset?: string[]; // [left,top] [10px, 10px] 不传默认居中定位
      shade?: boolean; // 是否显示遮罩
      fullScreenZIndex?: 'auto' | 'fixed' | number; // 全屏状态下的zIndex值
      onClose?: Function; // 关闭的回调事件
      onOpen?: Function; // 弹窗打开回调事件
      zIndexDefault?: number; //弹框默认z-index层级
    }
  | string;

/**
 * 弹窗生成器
 * @param config
 * @returns Dialog
 */
export const Dialog = (config: DialogConfig) => {
  // 可以只传cid，即获取dialog
  if (typeof config === 'string') {
    return dialogMap.get(config);
  }

  const {
    content,
    draggable = true,
    cid,
    data,
    offset,
    onClose,
    onOpen,
    shade,
    fullScreenZIndex,
    zIndexDefault,
  } = config;
  const isFullScreen = ref<boolean>(false);
  const dialogOffset = ref(offset);

  // 避免重复打开
  if (dialogMap.has(cid)) {
    return;
  }

  dialogMap.set(cid, {});

  dialogNormalize(cid);

  // 实例化组件
  const instance = useCreateApp(DialogVue, {
    cid,
    content,
    draggable,
    propsData: data,
    offset: dialogOffset,
    shade,
    isFullScreen,
    fullScreenZIndex,
    zIndexDefault,
    onOpen,
  });

  // 挂载组件
  const el = document.createElement('div');
  document.body.appendChild(el);
  instance.mount(el);

  // 卸载组件
  const unmount = () => {
    onClose?.();
    instance.unmount();
    document.body.removeChild(el);
    dialogMap.delete(cid);
  };

  /**
   * 弹窗全屏
   * 不传参数就取之前相反值
   * @param data 是否全屏
   */
  const fullScreen = (data?: boolean) => {
    if (typeof data === 'undefined') {
      isFullScreen.value = !isFullScreen.value;
      return;
    }
    isFullScreen.value = data;
  };

  // set offset
  const setOffset = (opt: { left: string; top: string }) => {
    const { left, top } = opt;
    dialogOffset.value = [left, top];
  };

  // 弹窗方法
  const dialog = {
    close: unmount,
    fullScreen,
    setOffset,
  };

  setZIndex(cid);
  dialogMap.set(cid, dialog);

  return dialog;
};

export const zIndexSet = ref<string[]>([]);
let timer: TimeoutHandle;

/**
 * set dialog zIndex
 * @param cid 弹窗id
 * @param isClick 是否是点击弹窗,让弹窗居顶
 * @returns
 */
export const setZIndex = (cid: string, isClick?: boolean) => {
  if (isClick) {
    if (timer) return;
  } else {
    timer = setTimeout(() => {
      clearTimeout(timer);
    }, 500);
  }
  const index = zIndexSet.value.indexOf(cid);
  if (index !== -1) {
    zIndexSet.value.splice(index, 1);
  }
  zIndexSet.value.push(cid);
};

/**
 * 弹窗规范-打开弹窗时需要关闭一些弹窗
 * @param {*} cid
 */
function dialogNormalize(cid: string) {
  const cidList = [
    'groupDetailCard',
    'createControlTask',
    'editPrivateCard',
    'create_dynamic_group',
    'trackCard',
    'realTimeTrackCard',
    'create_monitors_group',
    'chooseConferenceMember',
    'Setting',
  ];

  cidList.forEach((item) => {
    if (cid.includes(item)) return;

    for (const key of dialogMap.keys()) {
      if (key.replace(item, '') !== key) {
        const d = dialogMap.get(key);
        d.close(key);
      }
    }
  });
}

// 获取所有的弹窗cid
export function getDialogCidList(): string[] {
  const keys: string[] = [];
  for (const key of dialogMap.keys()) {
    keys.push(key);
  }
  return keys;
}

// 关闭所有弹窗
export function closeAllDialog() {
  for (const key of dialogMap.keys()) {
    Dialog(key)?.close();
  }
}
